//
//  DUCalSelectedView.swift
//  SimpleCal
//
//  Created by 杜晓祥 on 2021/11/24.
//

import Cocoa

@IBDesignable
class DUCalSelectedView: NSView {

    private var firstCal:DUPopMonthView!
    private var secondCal:DUPopMonthView!
    private var preButton: DUCalImgButton!
    private var nextButton: DUCalImgButton!
    private var confirmButton: DUCalTextButton!
    private var cancelButton: DUCalTextButton!
    private var firstDate: SolarEntity?
    var updateData: ((_ holiday: Int, _ work: Int, _ festival: Int) -> Void)?
    var confirmHandler: ((_ sender: [BaseViewButton.StateValue: [DateEntity]]) -> Void)?
    
    var selectedAllChange = [BaseViewButton.StateValue: [DateEntity]]()
    
    init() {
        super.init(frame: NSRect.zero)
        initialize()
    }
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        initialize()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        initialize()
    }
    
    private func initialize() {
        
        self.setFrameSize(NSSize(width: 210, height: 266))
        firstCal = DUPopMonthView(frame: NSMakeRect(0, 36, 210, 230))
        firstCal.titleType = .own
        firstCal.borderWidth = 0
        firstCal.bottomLineIsHidden = false
        firstCal.onChange = onCalChange
        addSubview(firstCal)
        secondCal = DUPopMonthView(frame: NSMakeRect(210, 36, 210, 230))
        secondCal.borderWidth = 0
        secondCal.titleType = .own
        secondCal.bottomLineIsHidden = false
        secondCal.isHidden = true
        secondCal.onChange = onCalChange
        addSubview(secondCal)
        
        preButton = DUCalImgButton(frame: NSRect(x: 3, y: 239, width: 25, height: 25))
        preButton.image = NSImage(named: "preIcon")
        preButton.labelId = "preButton"
        preButton.onClick = onClick
        addSubview(preButton)
        nextButton = DUCalImgButton(frame: NSRect(x: 182, y: 239, width: 25, height: 25))
        nextButton.image = NSImage(named: "nextIcon")
        nextButton.labelId = "nextButton"
        nextButton.onClick = onClick
        addSubview(nextButton)
        
        cancelButton = DUCalTextButton(frame: NSMakeRect(self.frame.width - 140, 10, 60, 26))
        cancelButton.settingStyle = .cancel
        cancelButton.buttonText = "重置"
        cancelButton.labelId = "cancel"
        cancelButton.onClick = stateButtonClick
        addSubview(cancelButton)
        confirmButton = DUCalTextButton(frame: NSMakeRect(self.frame.width - 70, 10, 60, 26))
        confirmButton.settingStyle = .confirm
        confirmButton.buttonText = "确定"
        confirmButton.labelId = "confirm"
        confirmButton.onClick = stateButtonClick
        addSubview(confirmButton)
    }
    
    private func stateButtonClick(button: BaseViewButton, event: NSEvent) {
        let b = button as! DUCalTextButton
        if b.labelId == "cancel" {
            firstCal.cleanSelected()
            secondCal.cleanSelected()
            selectedAllChange.removeAll()
        } else if b.labelId == "confirm" {
            confirmHandler?(selectedAllChange)
        }
    }
    
    override func layout() {
        firstCal.layer?.borderWidth = 0
        secondCal.layer?.borderWidth = 0
        self.layer?.borderWidth = 0
        let w = self.frame.width
        nextButton.setFrameOrigin(NSPoint(x: w - 28, y: 239))
        cancelButton.setFrameOrigin(NSPoint(x: w - 140, y: 5))
        confirmButton.setFrameOrigin(NSPoint(x: w - 70, y: 5))
    }
    
    func onClick(_ params: BaseViewButton, event: NSEvent) {
        let b = params as! DUCalImgButton
        if b.labelId == nil {
            return
        }
        if firstDate == nil {
            return
        }
        if b.labelId == "preButton" {
            secondCal.setDate(year: firstDate!.year, month: firstDate!.month, day: 1, selecteds: mergeSelected())
            firstDate = CalendarUtil.monthDec(solar: firstDate!)
            firstCal.setDate(year: firstDate!.year, month: firstDate!.month, day: 1, selecteds: mergeSelected())
        } else if b.labelId == "nextButton" {
            firstDate = CalendarUtil.monthInc(solar: firstDate!)
            firstCal.setDate(year: firstDate!.year, month: firstDate!.month, day: 1, selecteds: mergeSelected())
            let f = CalendarUtil.monthInc(solar: firstDate!)
            secondCal.setDate(year: f.year, month: f.month, day: 1, selecteds: mergeSelected())
        }
    }
    
    private func onCalChange(_ sender: DateEntity, _ state: BaseViewButton.StateValue) {
        deleteSelected(sender: sender, state: state)
        if state == .off {
            let h = stateCount(state: .holiday)
            let w = stateCount(state: .work)
            let f = stateCount(state: .on)
            updateData?(h, w, f)
            return
        }
        var b = selectedAllChange[state]
        if b == nil {
            b = [DateEntity]()
        }
        var d = sender
        switch state {
            case .holiday:
                d.dayType = .holiday
            case .on:
                d.dayType = .festvial
            case .work:
                d.dayType = .work
            default :
                break
        }
        b!.append(d)
        selectedAllChange.updateValue(b!, forKey: state)
        let h = stateCount(state: .holiday)
        let w = stateCount(state: .work)
        let f = stateCount(state: .on)
        updateData?(h, w, f)
    }
    
    private func stateCount(state: BaseViewButton.StateValue) -> Int {
        var h = 0
        if let h1 = selectedAllChange[state] {
            h = h1.count
        }
        return h
    }
    
    private func mergeSelected () -> [DateEntity] {
        var mergeAll = [DateEntity]()
        for e in BaseViewButton.StateValue.allCases {
            if let n = selectedAllChange[e] {
                mergeAll = mergeAll + n
            }
        }
        return mergeAll
    }
    
    private func deleteSelected (sender: DateEntity, state: BaseViewButton.StateValue) {
        for e in BaseViewButton.StateValue.allCases {
            if var n = selectedAllChange[e] {
                if let i = n.firstIndex(where: {$0.equal(date: sender)}) {
                    n.remove(at: i)
                    selectedAllChange.updateValue(n, forKey: e)
                }
            }
        }
    }
    
    func setDate (year:Int, month:Int) {
        var s = CalendarUtil.getSolarEntity(year: year, month: month, day: 1)
        self.firstDate = s
        firstCal.setDate(year: s.year, month: s.month, day: 1, selecteds: mergeSelected())
            s = CalendarUtil.monthInc(solar: s)
            secondCal.setDate(year: s.year, month: s.month, day: 1, selecteds: mergeSelected())
    }
    
    @IBInspectable var multCalInHidden:Bool = true {
        didSet {
            self.secondCal.isHidden = multCalInHidden
            if !multCalInHidden {
                self.setFrameSize(NSSize(width: 420, height: self.frame.height))
                
            }
        }
    }
    
}
